﻿Imports mshtml
Imports SHDocVw
Imports System.Net.Mail
Imports System.Threading
Imports log4net
Imports log4net.Config
Imports System.Runtime.InteropServices

Public Class BocDownloader
    Private Shared ReadOnly STR_BOC_LOGIN As String

    Private Shared ReadOnly dnLog As ILog = LogManager.GetLogger("BocDownloader")

    Shared Sub New()

        STR_BOC_LOGIN = GetSetting(modMain.REG_APP_NAME, modMain.REG_APP_MAIN, "loginUrl", String.Empty)
        XmlConfigurator.Configure()
    End Sub

    Const MAX_PAGE_WAIT As Integer = 500

    Private ie As SHDocVw.WebBrowser
    Private navCompleted As Boolean = False
    Private mailmsg As String
    Private totalAvBalance As Decimal

    Public Property BocPassword() As String
    Public Property BocUsername() As String

    Public Property SmtpPass() As String

    Public Property SmtpUname() As String
    Public Property SmtpPort() As Integer = 587

    Public Property Email1 As String
    Public Property Email2 As String

    Public Property SmtpServer As String

    Public Property SmtpServerEnableSSL As Boolean = True

    Public Property ieVisible As Boolean

    Private Property isBocLoggedIn As Boolean

    ''' <summary>
    ''' Note: if you are going to run this as a scheduled task  in Windows 7 be sure
    ''' to select "Run with highest privilages" option
    ''' </summary>
    ''' <remarks></remarks>
    Sub runDownload()
        Try
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA)
            ie = CType(CreateObject("InternetExplorer.Application"), SHDocVw.WebBrowser)
            'ie = New SHDocVw.WebBrowser
            dnLog.Info("ie object created ok.")

            ie.Visible = ieVisible
            dnLog.Info("set ie object visible=" & ieVisible)

            Call bocLogin()

            If (Not Me.isBocLoggedIn) Then
                dnLog.Error("Login Failed!")
                Exit Sub
            End If

            Call GotoMainAccountPage()
            Call bocGetAllAccountsInfo()

        Finally
            If ie IsNot Nothing Then
                ie.Quit()
                Marshal.ReleaseComObject(ie)
            End If

        End Try

        dnLog.Info("got info, will sent email")

        Call sendMail("Today's available Balance:" & totalAvBalance, mailmsg)

    End Sub

    Private Sub bocAccountInformation(ByVal doc As IHTMLDocument3, _
                                      ByVal accountNumber As String, ByVal accountIndex As Integer)

        Dim inputs As IHTMLElementCollection = doc.getElementsByTagName("a")
        Dim anchor As DispHTMLAnchorElement = Nothing
        For i As Integer = 0 To inputs.length - 1
            anchor = CType( _
                       inputs.item(i),  _
                       DispHTMLAnchorElement)

            If anchor.title = accountNumber Then
                Exit For
            End If
        Next
        If anchor Is Nothing Then
            dnLog.Info("Failed to get Account link for:" & accountNumber)
            Throw New ApplicationException("Getting acount anchor to BOC failed")
        End If

        anchor.click()

        Call checkDocumentLoad("form1:mainLp:availableBalStCommon")

        doc = CType(ie.Document, IHTMLDocument3)
        Dim avBalance As IHTMLElement = doc.getElementById("form1:mainLp:availableBalStCommon")
        Dim curBalance As IHTMLElement = doc.getElementById("form1:mainLp:currentBalStCurrent")

        Dim lAvBalanceinnerHTML As String = avBalance.innerHTML.Replace(".", "")
        lAvBalanceinnerHTML = lAvBalanceinnerHTML.Replace(",", ".")
        totalAvBalance = totalAvBalance + CDec(lAvBalanceinnerHTML)

        mailmsg = mailmsg & "Available Balance:" + avBalance.innerHTML + _
                  ", Current Balance:" + curBalance.innerHTML


        anchor = CType(doc.getElementById("HeaderFragment:mainLp:menuForm:j_id10"),  _
                        DispHTMLAnchorElement)
        anchor.click()
        Call checkDocumentLoad("form1:mainLp1:table1:tableRowGroup1:0:tableColumn1:img10t")
        anchor = CType(doc.getElementById("form1:mainLp1:table1:tableRowGroup1:" & accountIndex & ":tableColumn1:img10t"),  _
                        DispHTMLAnchorElement)
        anchor.click()

        Call checkDocumentLoad("form1:mainLp:table1:_table")
        'Dim selaccount = "BOC-CY-ACCOUNT-01181200606300       "

        doc = CType(ie.Document, IHTMLDocument3)
        Dim tbl As DispHTMLTable = CType(doc.getElementById("form1:mainLp:table1:_table"), DispHTMLTable)
        tbl.border = 1
        tbl.deleteRow(0)
        tbl.className = ""
        mailmsg = mailmsg & vbCrLf & tbl.outerHTML & "<hr>"
        'org.codegen.common.CommonUtils.TextFromFileSave("table.txt", tbl.outerHTML)
        dnLog.Info("Retrieved all info for account:" & accountNumber)
        Me.GotoMainAccountPage()

    End Sub

    Private Sub GotoMainAccountPage()
        'goto main account page
        ie.Navigate2(GetSetting(modMain.REG_APP_NAME, modMain.REG_APP_MAIN, "urlMainAccountPage", String.Empty))
        Do While ie.ReadyState <> tagREADYSTATE.READYSTATE_COMPLETE
            Thread.Sleep(1000)
        Loop
    End Sub

    Private Sub bocGetAllAccountsInfo()

        Call checkDocumentLoad("form1_hidden")
        Dim doc As IHTMLDocument3 = CType(ie.Document, IHTMLDocument3)

        Call Me.bocAccountInformation(doc, "011812006063", 1)
        Call Me.bocAccountInformation(doc, "357005502913", 0)

    End Sub

    Private Sub bocLogin()

        dnLog.Info("Going to " & STR_BOC_LOGIN)
        ie.Navigate(STR_BOC_LOGIN)
        Call checkDocumentLoad("form1:layoutPanel1:dynamicGridPanel")

        dnLog.Info("Login page accessed OK.")
        Dim doc As IHTMLDocument3 = CType(ie.Document, IHTMLDocument3)
        Dim tmp As IHTMLElement2 = CType(doc.getElementById("form1:layoutPanel1:dynamicGridPanel"), IHTMLElement2)
        Dim inputs As IHTMLElementCollection = tmp.getElementsByTagName("input")
        If (inputs Is Nothing OrElse inputs.length = 0) Then
            dnLog.Info("Cannot get inputs under form1:layoutPanel1:dynamicGridPanel")
            Exit Sub
        End If

        Dim unameField As DispHTMLInputElement = CType(inputs.item(0), DispHTMLInputElement)

        Dim passField As DispHTMLInputElement = CType(doc.getElementById("form1:layoutPanel1:passwordTf_field"), DispHTMLInputElement)
        Dim loginBtn As DispHTMLButtonElement = CType(doc.getElementById("form1:layoutPanel1:loginBtn"),  _
                                DispHTMLButtonElement)

        If (passField Is Nothing) Then
            dnLog.Info("Password field not found")
            Exit Sub
        End If


        If (loginBtn Is Nothing) Then
            dnLog.Info("login Button not found")
            Exit Sub
        End If

        If (unameField Is Nothing) Then
            dnLog.Info("Username control not found")
            Console.Write("Username control is null")
            Exit Sub
        End If

        passField.value = Me.BocPassword
        unameField.value = Me.BocUsername
        loginBtn.click()


        'the id below is for the Transfers &amp; Payments menu item
        Call checkDocumentLoad("form1:layoutPanel1:pageTitleLbl1")

        Me.isBocLoggedIn = True

    End Sub

    Sub checkDocumentLoad(ByVal controlID As String)

        Dim numDelays As Integer = 0
        Dim loaded As Boolean = False
        dnLog.Info("Will wait for " & MAX_PAGE_WAIT & " secs for control id: " & controlID & ".")

        Do While loaded = False AndAlso numDelays < MAX_PAGE_WAIT
            numDelays = numDelays + 1

            If (numDelays = MAX_PAGE_WAIT) Then
                Throw New ApplicationException("Page not loaded after waiting for seconds:" & _
                                               MAX_PAGE_WAIT & " for controlID:" & controlID)
            End If

            Thread.Sleep(1000)
            Dim doc As IHTMLDocument3 = Nothing
            Try
                doc = CType(ie.Document, IHTMLDocument3)
            Catch ex As Exception
                dnLog.Info("Exception thrown when trying to get read document proprty of ie." + ex.Message)
            End Try

            If (doc Is Nothing) Then
                Continue Do
            End If
            Dim controlRef As Object = doc.getElementById(controlID)
            If (controlRef Is Nothing) Then
                dnLog.Info(controlID & ":Still Waiting after " & numDelays & " pauses")
            Else
                dnLog.Info(controlID & " found, loaded after " & numDelays & " pauses")
                Exit Sub
            End If
        Loop


        Return

    End Sub

    Sub sendMail(ByVal subject As String, ByVal msg As String)

        Dim smtpServer As New SmtpClient()
        Dim mail As New MailMessage()
        smtpServer.Credentials = New Net.NetworkCredential(Me.SmtpUname, Me.SmtpPass)
        smtpServer.Port = Me.SmtpPort
        smtpServer.Host = Me.SmtpServer
        smtpServer.EnableSsl = Me.SmtpServerEnableSSL

        mail = New MailMessage()
        mail.IsBodyHtml = True
        mail.From = New MailAddress("christoforosl08@gmail.com")
        mail.To.Add(Me.Email1)

        'If Not String.IsNullOrEmpty(Me.Email2) Then
        '    mail.To.Add(Me.Email2)
        'End If

        mail.Subject = subject
        mail.Body = "<html><body>" & msg & "</body></html>"

        smtpServer.Send(mail)
        dnLog.Info("Message Sent")

    End Sub

    Function configComplete() As Boolean

        Return String.IsNullOrEmpty(BocPassword()) = False AndAlso _
                String.IsNullOrEmpty(BocUsername()) = False AndAlso _
                String.IsNullOrEmpty(SmtpPass()) = False AndAlso _
                String.IsNullOrEmpty(SmtpUname()) = False AndAlso _
                CInt(SmtpPort()) > 0 AndAlso _
                String.IsNullOrEmpty(Email1) = False AndAlso _
                String.IsNullOrEmpty(SmtpServer) = False

    End Function



End Class
